<?php

namespace app\admin\controller\outhouse;
use app\common\controller\Backend;
use think\Db;
use think\Exception;
use app\admin\model\information\InventoryClass;
use app\admin\model\inventory\Temporary;
use app\admin\model\inventory\Wmskc;
use app\admin\model\outhouse\Kcmx;
/**
 * 调拨单据管理
 *
 * @icon fa fa-circle-o
 */
class Checkvouch extends Backend
{

    /**
     * Tpdj模型对象
     * @var
     */
    protected $model = null;
    protected $modelItem = null;
    protected $modelCode = null;
    protected $typeArr = [];
    protected $warehouseArr = [];
    protected $pdaFlagArr = [];
    protected $pdaUserArr = [];
    protected $pdaFlagArrFlip = [];
    
    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\outhouse\CheckVouch;
        $this->modelItem = new \app\admin\model\outhouse\CheckVouchList;
        $this->modelCode = new \app\admin\model\Mcode;
        
        $this->typeArr = $this->model->getTypeList();
        $this->warehouseArr = \app\common\model\Warehouse::getWarehouse(['switch'=>1]);
        $this->pdaFlagArr = config('site.pda_flag');
        $this->pdaUserArr = config('site.pda_user');
        
        $this->assign('typeArr',$this->typeArr);
        $this->assign('warehouseArr',$this->warehouseArr);
        $this->assign('selectedPdaFlagArr',$this->pdaFlagArr);
        
        $pdaFlagArrFlip = array_flip($this->pdaFlagArr);
        if ($pdaFlagArrFlip){
            foreach ($pdaFlagArrFlip as $key => &$val){
                if(isset($this->pdaUserArr[$val])){
                    $val = $val.' - '.$this->pdaUserArr[$val];
                }
            }
        }
        
        $this->pdaFlagArrFlip = $pdaFlagArrFlip;
        $this->assign('pdaFlagArr',$pdaFlagArrFlip);
        $this->assign('pdaUserArr',$this->pdaUserArr);
        $this->assign('statusArr',$this->model->getStatusList());
    }

    public function index()
    {
        $this->request->filter(['strip_tags', 'trim']);
        if (false === $this->request->isAjax()) {
            return $this->view->fetch();
        }
        //如果发送的来源是 Selectpage，则转发到 Selectpage
        if ($this->request->request('keyField')) {
            return $this->selectpage();
        }
        
        $this->searchFields = 'code,warehouse_code,remark';
        
        [$where, $sort, $order, $offset, $limit] = $this->buildparams();
        $list = $this->model
            ->with(['wareHouse'])
            ->where($where)
            ->order($sort,$order)
            ->paginate($limit);
        
            foreach ($list as &$item){
                $pda_user_arr = [];
                if($item->pda){
                    $padarr = explode('|', $item->pda);
                    if ($padarr){
                        foreach($padarr as $pad){
                            if(isset($this->pdaFlagArrFlip[$pad])){
                                $pda_user_arr[] = $this->pdaFlagArrFlip[$pad];
                            }
                        }
                    }
                    if($pda_user_arr){
                        $item->pda = implode(',', $pda_user_arr);
                    }
                }
            }
            
        $result = ['total' => $list->total(), 'rows' => $list->items()];
        return json($result);
    }
    public function addList($wms_kc,$code){
        foreach ($wms_kc as $k => $v) {
            $list[] = array_merge($v,['code'=>$code]);
        }
        //表体
        $this->modelItem->saveAll($list);
    }
    public function add(){

        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if (empty($params)) {
                $this->error(__('Parameter %s can not be empty', ''));
            }
            if (empty($params['warehouse_id'])) {
                $this->error('没有选择仓库');
            }
            
            try {
                Db::startTrans();
                $type = intval($params['type']);
                $where = [
                    'warehouse_id' => $params['warehouse_id'],
                    'quantity' => ['GT',0]
                ];
                switch ($type){
                    case 1://所有库存
                        
                        break;
                    case 2:
                        if(!$params['inv_number_start']&&!$params['inv_number_end']){
                            exception('物料编码区间不能为空');
                        }
                        if($params['inv_number_start']&&$params['inv_number_end']){
                            $where['inv_number'] = ['between',[$params['inv_number_start'],$params['inv_number_end']]];
                        }else if(!$params['inv_number_start']&&$params['inv_number_end']){
                            $where['inv_number'] = ['LT' , $params['inv_number_end']];
                        }else if($params['inv_number_start']&&!$params['inv_number_end']){
                            $where['inv_number'] = ['GT' , $params['inv_number_start']];
                        }
                        break;
                    case 3://库区、货架
                        if(!$params['shelves_ids']){
                            exception('货架、库区不能为空');
                        }
                        $where['shelves_id'] = ['IN' , explode(',', $params['shelves_ids'])];
                        break;
                    case 4:
                        $inv_class1_ids = $params['inv_class1_id'];
                        $inv_class2_ids = $params['inv_class2_id'];
                        $inv_class3_ids = $params['inv_class3_id'];
                        $invClassModel = new InventoryClass();
                        $inv_class_ids = '';
                        if($inv_class3_ids){
                            //有3级
                            $inv_class_ids = $inv_class3_ids;
                        }else {
                            //有2级
                            if($inv_class2_ids){
                                $inv_class_ids = $inv_class2_ids;
                            }else{
                                if($inv_class1_ids){
                                    //只有1级
                                    $inv_class_ids = $inv_class1_ids;
                                }
                            }
                        }
                        
                        if(!$inv_class_ids){
                            exception('物料分类不能为空');
                        }
                        
                        $inv_class_ids_arr = explode(',', $inv_class_ids);
                        $inv_class_name_arr = db('inventory_class')->where(['id'=>['in',$inv_class_ids_arr]])->column('cInvCName');
                        $params['inv_class_name'] = implode(',', $inv_class_name_arr);
                        
                        $cids = [];
                        //循环增加
                        foreach ($inv_class_ids_arr as $inv_class_id){
                            $childIdsArr = $invClassModel->getChildIds($inv_class_id);
                            if($childIdsArr){
                                foreach ($childIdsArr as $cid){
                                    $cids[] = $cid;
                                }
                            }
                        }
                        $classification_id = db('inventory_class')->where([
                            'id' => ['IN',$cids]
                        ])
                        ->column('cInvCCode');
                        
                        $where['classification_id'] = ['IN' , $classification_id];
                        break;
                }
                
                $wms_kc = db('wms_kc')->where($where)
                ->field('inv_id,inv_name,inv_number cInvCode,shelves_id,shelves_name,quantity iQuantity,cBatch')
                ->select();
                
                if(!$wms_kc){
                    //exception('库存记录为空');
                }
                
                if($params['pda']){
                    $params['pda'] = implode('|', $params['pda']);
                }
                
                $this->model->allowField(true)->save($params);
                if($wms_kc){
                    $this->addList($wms_kc,$params['code']);
                }
                
                Db::commit();
            }catch (\Exception $e){
                Db::rollback();
                $this->error($e->getMessage());
            }
            $this->success();
        }
        
        $this->assign('code',$this->modelCode::getCode(1));
        return $this->fetch();
    }

    public function edit($ids = null){
        $row  = $this->model->where('id',$ids)->find();
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if (empty($params)) {
                $this->error(__('Parameter %s can not be empty', ''));
            }
            if (empty($params['warehouse_id'])) {
                $this->error('没有选择仓库');
            }
            
            if($params['pda']){
                $params['pda'] = implode('|', $params['pda']);
            }
            
            try{
                Db::startTrans();
                $basic_json = $params['basic'];
                $basic_arr = json_decode($basic_json, true);
                
                if ($basic_arr){
                    foreach ($basic_arr as $basic){
                        $conditon = [
                            'iCVCQuantity'=>$basic['iCVCQuantity']
                        ];
                        if(trim($basic['scantime'])){
                            $conditon['scantime'] = date('Y-m-d H:i:s', strtotime($basic['scantime']));
                        }
                        $this->modelItem->update($conditon,['id'=>$basic['id']]);
                    }
                }
                $row->allowField(true)->save($params);
                Db::commit();
            }catch (\Exception $e){
                Db::rollback();
                $this->error($e->getMessage());
            }
            $this->success('edit');
        }
        
        if($row->pda){
            $row->pda = explode('|', $row->pda);
        }
        
        $list = $this->modelItem->alias('c')
            ->join('inventory i','i.number=c.cInvCode','left')
            ->field('c.*,i.name,i.number')
            ->where([
                'c.code' =>$row['code'],
                //'c.deletetime' => null
            ])
            ->order('scan_flag desc,cInvCode')
            ->select();
        $this->assign('list_json',json_encode($list));
        $this->assign('row',$row);
        return $this->fetch();
    }
    
    /**
     * 删除
     *
     * @param $ids
     * @return void
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function del($ids = null)
    {
        if (false === $this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ?: $this->request->post("ids");
        if (empty($ids)) {
            $this->error(__('Parameter %s can not be empty', 'ids'));
        }
        $pk = $this->model->getPk();
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $this->model->where($this->dataLimitField, 'in', $adminIds);
        }
        
        $list = $this->model->where($pk, 'in', $ids)->select();
        
        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                
                //检查是否被pda引用，是则先取删除pda单再来删盘点单
                if(db('temporary')->where(['source_code' => $item->code])->find()){
                    exception('该盘点单已被PDA单据引用，请先删除PDA单据');
                }
                
                $this->modelItem->where('code',$item->code)->delete();
                $count += $item->delete();
            }
            Db::commit();
        } catch (PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error(__('No rows were deleted'));
    }
    
    /**
     * 删除明细
     *
     * @param $ids
     * @return void
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function delitem($ids = null)
    {
        if (false === $this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ?: $this->request->post("ids");
        if (empty($ids)) {
            $this->error(__('Parameter %s can not be empty', 'ids'));
        }
        
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $this->model->where($this->dataLimitField, 'in', $adminIds);
        }
        
        $list = $this->modelItem->where('id', 'in', $ids)->select();
        
        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                $count += $item->delete();
            }
            Db::commit();
        } catch (PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error(__('No rows were deleted'));
    }

    /**
     * 获取盘点单列表
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getCheckList(){
        [$where, $sort, $order, $offset, $limit] = $this->buildparams();
        $row = Db::name('check_vouch_list')
               ->alias('c')
               ->join('inventory i','i.number=c.cInvCode','left')
               ->field('c.*,i.name,i.number')
               ->where(['c.code' => $this->request->request('code')])
               ->select();
        return json(['rows'=>$row,'total'=>count($row)]);
    }

    /**更新盘点单
     * @param $ids
     * @return void
     */
    public function checkStatus($ids  = null){
        $where = ['id'=>$ids,'status'=>0];
        $info  = $this->model->where($where)->find();
        if(empty($info)){
            $this->error('盘点单状态已经改变');
        }
        //
        $this->model->where($where)->update(['status'=>1]);
        $this->success();
    }
    /**
     * 插入中间库
     * @param $data
     * @param $list
     * @return void
     * @throws \think\Exception
     */
    public function insertMiddlData($data,$list)
    {
        //插入中间库
        $insert_id = Db::connect('database.inc')->table('TransVouch')->insertGetId([
            'cTVCode' => $data['code'],
            'dTVDate' =>$data['code_date'] ,
            'cOWhCode' => $data['warehouse_code'],
            'cIWhCode' => $data['change_warehouse_code'],
            'dnmodifytime'=>date('Y-m-d H:i:s'),
            'ID'=>time(),
        ]);
        foreach ($list as $k=>$v){
            Db::connect('database.inc')->table('TransVouchs')->insert([
                'cTVCode'=>$data['code'],
                'cInvCode'=>$v['cInvCode'],
                'ID' => $insert_id,
                'autoID'=>time(),
                'iTVQuantity' => $v['iQuantity'],
            ]);
        }
    }

    /*
     * 一键清理并重盘
     *   */
    public function oneKeyClearAndRecheck(){
        if ($this->request->isPost()) {
            $temp_id = $this->request->post('id',0);
            $temp_row = Temporary::get($temp_id);
            if(!$temp_row){
                $this->error(__("Invalid parameters"));
            }
            if($temp_row->status!=2){
                $this->error('该盘点单状态不是关闭，不能执行此操作');
            }
            
            //盘点单 表头
            $checkvouch = $this->model::where('code',$temp_row->source_code)->find();
            if(!$checkvouch){
                $this->error('该盘点单不存在，请核实');
            }
            if($checkvouch->status!=2){
                $this->error('该盘点单状态非完成状态，请核实');
            }
            
            //所有扫描过的盘点明细
            $list = $this->modelItem::where([
                'code' => $temp_row->source_code,
                'temporary_id' => $temp_id,
                'deletetime' => null,
                'scantime' => ['neq','not null'] //扫描时间不为空
            ])
            ->field('id,inv_id,inv_name,cInvCode,kc_quantity,iQuantity,iAdInQuantity,iAdOutQuantity,iCVCQuantity,duringIn,duringOut,shelves_id,shelves_name,isnew,scantime')
            ->select();
            
            if(!$list){
                $this->error('该盘点单无已扫描盘点明细，请核实');
            }
            
            $newItems = [];
            $newItemsIds = [];
            $code = $this->modelCode::getCode(1);
            foreach ($list as $item){
                try{
                    //检查每天盘点记录的
                    //得到期间入和出
                    $duringInOutArr = Kcmx::getKcmxQtyByDuringDate($checkvouch->warehouse_id, $item->shelves_id,$item->cInvCode,$item->scantime);
                    //即时库存
                    $kc_qty = Wmskc::getKcQty($checkvouch->warehouse_id , $item->shelves_id, $item->cInvCode);
                    $item->kc_quantity = $kc_qty;//即时库存
                    $item->duringIn = $duringInOutArr['in'];
                    $item->duringOut = $duringInOutArr['out'];
                    $item->iAdOutQuantity = 0;//初始化盘亏0
                    
                    //盘点+（期间入-期间出） - 即时库存  大于0的，针对期初出库的计算（按期初是0即时库存 - （盘点数+期间入-出）理解）
                    $duringQuantity = round($kc_qty - ($item['iCVCQuantity']+$duringInOutArr['sy']),getDigits());
                    if($duringQuantity>0){
                        //其他出
                        $item->iAdInQuantity = 0;
                        $item->iAdOutQuantity = $duringQuantity;
                        //检查是否有库存可以扣
                        if($duringQuantity>$kc_qty){
                            exception('库存不足');
                        }
                    }
                }catch (\Exception $e){
                    //把有异常的明细id放入新数组,方便批量修改
                    $newItemsIds[] = $item->id;
                    //把有异常的明细放入新数组
                    
                    $item->code = $code;//赋值新盘点单号
                    $tarr = $item->toArray();
                    unset($tarr['id']);
                    unset($tarr['createtime']);
                    unset($tarr['updatetime']);
                    $newItems[] = $tarr;
                }
            }
            
            if(!$newItems){
                $this->error('该盘点单无盘点异常记录，请核实');
            }
            
            Db::startTrans();
            try {
                //新增表头
                $checkvouchArr = $checkvouch->toArray();
                unset($checkvouchArr['id']);
                unset($checkvouchArr['createtime']);
                unset($checkvouchArr['updatetime']);
                $checkvouchArr['code'] = $code;
                $this->model->allowField(true)->save($checkvouchArr);
                
                //新增表体
                $this->modelItem->allowField(true)->saveAll($newItems);
                
                //批量修改旧盘点记录
                $this->modelItem->update([
                    'deletetime' => date('Y-m-d H:i:s',time()),
                    'result' => '库存不足'
                ],[
                    'id' => ['IN',$newItemsIds]
                ]);
                
                //把pda单据表状态恢复为0，待处理，可重新复核
                $temp_row->status = 0;
                $temp_row->save();
                
                Db::commit();
            }catch (\Exception $e){
                $this->error($e->getMessage());
                Db::rollback();
            }
            $this->success();
        }
        $this->error(__("Invalid parameters"));
    }
    
    /*public function checkno(){
        if ($this->request->isPost()) {
            $order_code = $this->request->post('order_code','');
            $check_id = $this->modelItem::where([
                'code' => $order_code,
                'scan_flag' => 0,
                'deletetime' => null
            ])->value('id');
            if($check_id){
                $this->success();
            }else{
                $this->error();
            }
        }
    }*/
}